Flutter GPUSurfaceGL
GPUSurfaceGL 类是对 Flutter Surface 在 OpenGL 下的实现。该类位于 src/flutter/shell/gpu/gpu_surface_gl.h
。
MakeGLContext
在该方法中,调用 skia 的初始化,创建出 OpenGL 下的 GrDirectContext:
sk_sp<GrDirectContext> GPUSurfaceGL::MakeGLContext(GPUSurfaceGLDelegate* delegate) {
auto context_switch = delegate->GLContextMakeCurrent();
// ...
const auto options =
MakeDefaultContextOptionskRender, GrBackendApi::kOpenGL;
auto context = GrDirectContext::MakeGL(delegate->GetGLInterface(), options);
// ...
context->setResourceCacheLimits(kGrCacheMaxCount, kGrCacheMaxByteSize);
// ...
return context;
}
Skia 通过 GrDirectContext 类管理 GPU,有了 GrDirectContext,就能够用它创建 SkSurface 等绘制对象了。
谁调用 MakeGLContext?
GPUSurfaceGL 的构造函数:
GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate,
bool render_to_surface)
: GPUSurfaceGL(MakeGLContext(delegate), delegate, render_to_surface) {
context_owner_ = true;
}
在 AndroidSurfaceGL 中,有一个 CreateGPUSurface 方法,如果传入的 GrDirectContext 为空,则会调用这里的方法创建一个:
std::unique_ptr<Surface> AndroidSurfaceGL::CreateGPUSurface(
GrDirectContext* gr_context) {
if (gr_context) {
return std::make_unique<GPUSurfaceGL>(sk_ref_sp(gr_context), this, true);
} else {
sk_sp<GrDirectContext> main_skia_context =
GLContextPtr()->GetMainSkiaContext();
if (!main_skia_context) {
main_skia_context = GPUSurfaceGL::MakeGLContext(this);
GLContextPtr()->SetMainSkiaContext(main_skia_context);
}
return std::make_unique<GPUSurfaceGL>(main_skia_context, this, true);
}
}
构造方法
GPUSurfaceGL 拥有两个构造方法,区别在于 GrDirectContext 是否由自己创建,并且使用 context_owner_
成员标量表征是否是自己创建的。
GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate,
bool render_to_surface)
// 创建 `GrDirectContext` 对象
// 调用第二个构造函数
: GPUSurfaceGL(MakeGLContext(delegate), delegate, render_to_surface) {
context_owner_ = true;
}
GPUSurfaceGL::GPUSurfaceGL(sk_sp<GrDirectContext> gr_context,
GPUSurfaceGLDelegate* delegate,
bool render_to_surface)
: delegate_(delegate),
context_(gr_context),
context_owner_(false),
render_to_surface_(render_to_surface),
weak_factory_(this) {
// 尝试将OpenGL上下文切换到delegate_
auto context_switch = delegate_->GLContextMakeCurrent();
// 检查切换是否成功
if (!context_switch->GetResult()) {
FML_LOG(ERROR)
<< "Could not make the context current to set up the Gr context.";
return;
}
delegate_->GLContextClearCurrent();
// 表示这个 GPUSurfaceGL 是否有效
valid_ = gr_context != nullptr;
}
其中:GLContextMakeCurrent 到 GLContextClearCurrent 的作用是:
GLContextMakeCurrent
和GLContextClearCurrent
的调用是为了在设置GrDirectContext
(即gr_context
)时,确保正确的OpenGL上下文是当前活动的。
GLContextMakeCurrent
的调用是为了将OpenGL上下文切换到delegate_
。这是因为在设置GrDirectContext
时,需要确保正确的OpenGL上下文是当前活动的。如果不这样做,可能会在错误的上下文中设置GrDirectContext
,导致渲染错误。
然后,代码检查上下文切换是否成功。如果上下文切换失败,那么就记录一条错误日志并返回,不再执行后续的代码。
如果上下文切换成功,那么就调用GLContextClearCurrent
来清除当前的OpenGL上下文。这是因为在设置完GrDirectContext
后,不再需要OpenGL上下文,所以将其清除以防止后续的代码错误地使用这个上下文。
总的来说,GLContextMakeCurrent
和GLContextClearCurrent
的调用是为了确保在设置GrDirectContext
时,正确的OpenGL上下文是当前活动的,并在设置完GrDirectContext
后,清除当前的OpenGL上下文。
本文作者:Maeiee
本文链接:Flutter GPUSurfaceGL
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!